The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
Changes 07
META.yml 11
bin/cpanm 15541
lib/App/cpanminus.pm 1204
4 files changed (This is a version diff) 27653
@@ -1,5 +1,12 @@
 See http://github.com/miyagawa/cpanminus/ for the latest development.
 
+1.1004  Tue Nov 30 10:03:01 PST 2010
+   - Fixed a bug where uncompressed and compressed index timestamps are out of sync which causes
+     issues when the local and mirror server's clocks are out of sync (reported by sukria)
+
+1.1003  Thu Nov 25 01:17:28 PST 2010
+   - Fixed a bug where --mirror-only doesn't detect module version updates (reported by sukria)
+
 1.1002  Tue Nov 16 18:27:19 PST 2010
    - Implemented --auto-cleanup and set that to 7 (days) by default
 
@@ -1,6 +1,6 @@
 --- #YAML:1.0
 name:               App-cpanminus
-version:            1.1002
+version:            1.1004
 abstract:           Get, unpack, build and install modules from CPAN.
 author:  []
 license:            perl
@@ -18,7 +18,7 @@ my %fatpacked;
 
 $fatpacked{"App/cpanminus.pm"} = <<'APP_CPANMINUS';
   package App::cpanminus;
-  our $VERSION = "1.1002";
+  our $VERSION = "1.1004";
   
   =head1 NAME
   
@@ -45,7 +45,7 @@ $fatpacked{"App/cpanminus.pm"} = <<'APP_CPANMINUS';
   easy to install C<cpanm> to your system without thinking about where to
   install, and later upgrade.
   
-  You can also use the latest cpanminus to install cpanminus itself (aka bootstrap):
+  You can also use the latest cpanminus to install cpanminus itself:
   
       curl -L http://cpanmin.us | perl - --sudo App::cpanminus
   
@@ -80,19 +80,13 @@ $fatpacked{"App/cpanminus.pm"} = <<'APP_CPANMINUS';
   
   C compiler, if you want to build XS modules.
   
-  =back
-  
-  And optionally:
-  
-  =over 4
-  
   =item *
   
-  make, if you want to reliably install MakeMaker based modules
+  make
   
   =item *
   
-  Module::Build (core in 5.10) to install Build.PL based modules
+  Module::Build (core in 5.10)
   
   =back
   
@@ -119,64 +113,6 @@ $fatpacked{"App/cpanminus.pm"} = <<'APP_CPANMINUS';
   especially when all they want to do is just install some modules and start
   writing code.
   
-  In particular, here are the few issues I've observed:
-  
-  =over
-  
-  =item *
-  
-  They ask too many questions and do not provide enough sane defaults. A normal
-  user doesn't (and shouldn't have to) know what's the right answer for the
-  question C<Parameters for the 'perl Build.PL' command? []>
-  
-  =item *
-  
-  They provide very noisy output by default.
-  
-  =item *
-  
-  They fetch and rebuild their indexes almost every day, and this takes time.
-  
-  =item *
-  
-  ... and they hog 200MB of memory and thrashes/OOMs on my 256MB VPS
-  
-  =back
-  
-  cpanminus is designed to be very quiet (but logs all output to
-  C<~/.cpanm/build.log>) and to pick the sanest possible defaults without asking
-  any questions -- to I<just work>.
-  
-  Note that most of these problems with existing tools are rare, or are just
-  overstated.  They might already be fixed, or can be configured to work nicer.
-  For instance, the latest CPAN.pm dev release has a much better first time
-  configuration experience than ever before.
-  
-  I know there's a reason for them to have many options and questions, because
-  they're meant to work everywhere for everybody.
-  
-  Of course I should have contributed back to CPAN/CPANPLUS
-  instead of writing a new client, but CPAN.pm is nearly impossible
-  (for anyone other than andk or xdg) to maintain (that's why CPANPLUS
-  was born, right?) and CPANPLUS is a huge beast for me to start working
-  on.
-  
-  =head2 Are you on drugs?
-  
-  Yeah, I think my brain has been damaged since I looked at PyPI,
-  gemcutter, pip and rip. They're quite nice and I really wanted
-  something as nice for CPAN which I love.
-  
-  =head2 How does this thing work?
-  
-  Imagine you don't have CPAN or CPANPLUS. You search for a module on the CPAN
-  search site, download a tarball, unpack it and then run C<perl Makefile.PL> (or
-  C<perl Build.PL>). If the module has dependencies you probably have to resolve
-  those dependencies by hand before doing so. Then you run the unit tests and
-  C<make install> (or C<./Build install>).
-  
-  cpanminus automates that.
-  
   =head2 Zero-conf? How does this module get/parse/update the CPAN index?
   
   It queries the CPAN Meta DB site running on Google AppEngine at
@@ -201,58 +137,6 @@ $fatpacked{"App/cpanminus.pm"} = <<'APP_CPANMINUS';
   directory under your home directory. To avoid this, run the script as the root
   user, with C<--sudo> option or with C<--local-lib> option.
   
-  This L<local::lib> automatic integration is still considered alpha and
-  in the work -- more bootstrapping is under development. Stay tuned.
-  
-  =head2 Does this really work?
-  
-  I tested installing MojoMojo, Task::Kensho, KiokuDB, Catalyst, Jifty and Plack
-  using cpanminus and the installations including dependencies were mostly
-  successful. More than I<half of CPAN> behaves really nicely and appears to
-  work.
-  
-  However, there might be some distributions that will miserably fail, because of
-  nasty edge cases. Here are some examples:
-  
-  =over 4
-  
-  =item *
-  
-  Packages uploaded to PAUSE in 90s which don't live under the standard
-  C<authors/id/A/AA> directory hierarchy.
-  
-  =item *
-  
-  Distributions with a C<Makefile.PL> or C<Build.PL> that asks you questions
-  without using C<prompt> function. However cpanminus has a mechanism to kill
-  those questions with a timeout, and you can always say C<--interactive> to make
-  the configuration interactive.
-  
-  =item *
-  
-  Distributions that do not shipped with C<META.yml> file but do require
-  some specific version of toolchain for configuration.
-  
-  =item *
-  
-  Distributions that have a C<META.yml> file that is encoded in YAML 1.1 format
-  using L<YAML::XS>. This will be eventually solved once we move to C<META.json>.
-  
-  =back
-  
-  cpanminus intends to work for 99.9% of modules on CPAN for 99.9% of people. It
-  may not be perfect, but it should just work in most cases.
-  
-  If this tool doesn't work for your very rare environment, then I'm sorry, but
-  you should use CPAN or CPANPLUS, or build and install modules manually.
-  
-  =head2 That sounds fantastic. Should I switch to this from CPAN(PLUS)?
-  
-  If you have CPAN or CPANPLUS working then you may want to keep using
-  CPAN or CPANPLUS in the longer term, but I hope this can be a
-  quite handy alternative to them for people in other situations. And
-  apparently, many people love (at least the idea of) this software :)
-  
   =head1 COPYRIGHT
   
   Copyright 2010- Tatsuhiko Miyagawa
@@ -336,7 +220,7 @@ $fatpacked{"App/cpanminus/script.pm"} = <<'APP_CPANMINUS_SCRIPT';
   use constant WIN32 => $^O eq 'MSWin32';
   use constant SUNOS => $^O eq 'solaris';
   
-  our $VERSION = "1.1002";
+  our $VERSION = "1.1004";
   $VERSION = eval $VERSION;
   
   my $quote = WIN32 ? q/"/ : q/'/;
@@ -505,51 +389,53 @@ $fatpacked{"App/cpanminus/script.pm"} = <<'APP_CPANMINUS_SCRIPT';
   }
   
   sub package_index_for {
-    my ($self, $mirror) = @_;
-    return $self->source_for($mirror) . "/02packages.details.txt";
+      my ($self, $mirror) = @_;
+      return $self->source_for($mirror) . "/02packages.details.txt";
   }
   
   sub generate_mirror_index {
-    my ($self, $mirror) = @_;
-    my $file = $self->package_index_for($mirror);
-    my $gz_file = $file . '.gz';
-  
-    unless (-e $file && (stat $file)[9] >= (stat $gz_file)[9]) {
-      $self->chat("Uncompressing index file...\n");
-      if (eval {require Compress::Zlib}) {
-        my $gz = Compress::Zlib::gzopen($gz_file, "rb")
-          or do { $self->diag_fail("$Compress::Zlib::gzerrno opening compressed index"); return};
-        open my $fh, '>', $file
-          or do { $self->diag_fail("$! opening uncompressed index for write"); return };
-        my $buffer;
-        while (my $status = $gz->gzread($buffer)) {
-          if ($status < 0) {
-            $self->diag_fail($gz->gzerror . " reading compressed index");
-            return;
+      my ($self, $mirror) = @_;
+      my $file = $self->package_index_for($mirror);
+      my $gz_file = $file . '.gz';
+      my $index_mtime = (stat $gz_file)[9];
+  
+      unless (-e $file && (stat $file)[9] >= $index_mtime) {
+          $self->chat("Uncompressing index file...\n");
+          if (eval {require Compress::Zlib}) {
+              my $gz = Compress::Zlib::gzopen($gz_file, "rb")
+                  or do { $self->diag_fail("$Compress::Zlib::gzerrno opening compressed index"); return};
+              open my $fh, '>', $file
+                  or do { $self->diag_fail("$! opening uncompressed index for write"); return };
+              my $buffer;
+              while (my $status = $gz->gzread($buffer)) {
+                  if ($status < 0) {
+                      $self->diag_fail($gz->gzerror . " reading compressed index");
+                      return;
+                  }
+                  print $fh $buffer;
+              }
+          } else {
+              unless (system("gunzip -c $gz_file > $file")) {
+                  $self->diag_fail("Cannot uncompress -- please install gunzip or Compress::Zlib");
+                  return;
+              }
           }
-          print $fh $buffer;
-        }
-      } else {
-        unless (system("gunzip -c $gz_file > $file")) {
-          $self->diag_fail("Cannot uncompress -- please install gunzip or Compress::Zlib");
-          return;
-        }
+          utime $index_mtime, $index_mtime, $file;
       }
-    }
-    return 1;
+      return 1;
   }
   
   sub search_mirror_index {
-    my ($self, $mirror, $module) = @_;
+      my ($self, $mirror, $module) = @_;
   
-    open my $fh, '<', $self->package_index_for($mirror) or return;
-    while (<$fh>) {
-      if (m!^\Q$module\E\s+[\w\.]+\s+(.*)!m) {
-        return $self->cpan_module($module, $1);
+      open my $fh, '<', $self->package_index_for($mirror) or return;
+      while (<$fh>) {
+          if (m!^\Q$module\E\s+([\w\.]+)\s+(.*)!m) {
+              return $self->cpan_module($module, $2, $1);
+          }
       }
-    }
   
-    return;
+      return;
   }
   
   sub search_module {
@@ -1,5 +1,5 @@
 package App::cpanminus;
-our $VERSION = "1.1002";
+our $VERSION = "1.1004";
 
 =head1 NAME
 
@@ -26,7 +26,7 @@ search for cpanminus and use the appropriate command to install. This makes it
 easy to install C<cpanm> to your system without thinking about where to
 install, and later upgrade.
 
-You can also use the latest cpanminus to install cpanminus itself (aka bootstrap):
+You can also use the latest cpanminus to install cpanminus itself:
 
     curl -L http://cpanmin.us | perl - --sudo App::cpanminus
 
@@ -61,19 +61,13 @@ perl 5.8 or later.
 
 C compiler, if you want to build XS modules.
 
-=back
-
-And optionally:
-
-=over 4
-
 =item *
 
-make, if you want to reliably install MakeMaker based modules
+make
 
 =item *
 
-Module::Build (core in 5.10) to install Build.PL based modules
+Module::Build (core in 5.10)
 
 =back
 
@@ -100,64 +94,6 @@ their feet, setting up the CPAN toolchain often feels like yak shaving,
 especially when all they want to do is just install some modules and start
 writing code.
 
-In particular, here are the few issues I've observed:
-
-=over
-
-=item *
-
-They ask too many questions and do not provide enough sane defaults. A normal
-user doesn't (and shouldn't have to) know what's the right answer for the
-question C<Parameters for the 'perl Build.PL' command? []>
-
-=item *
-
-They provide very noisy output by default.
-
-=item *
-
-They fetch and rebuild their indexes almost every day, and this takes time.
-
-=item *
-
-... and they hog 200MB of memory and thrashes/OOMs on my 256MB VPS
-
-=back
-
-cpanminus is designed to be very quiet (but logs all output to
-C<~/.cpanm/build.log>) and to pick the sanest possible defaults without asking
-any questions -- to I<just work>.
-
-Note that most of these problems with existing tools are rare, or are just
-overstated.  They might already be fixed, or can be configured to work nicer.
-For instance, the latest CPAN.pm dev release has a much better first time
-configuration experience than ever before.
-
-I know there's a reason for them to have many options and questions, because
-they're meant to work everywhere for everybody.
-
-Of course I should have contributed back to CPAN/CPANPLUS
-instead of writing a new client, but CPAN.pm is nearly impossible
-(for anyone other than andk or xdg) to maintain (that's why CPANPLUS
-was born, right?) and CPANPLUS is a huge beast for me to start working
-on.
-
-=head2 Are you on drugs?
-
-Yeah, I think my brain has been damaged since I looked at PyPI,
-gemcutter, pip and rip. They're quite nice and I really wanted
-something as nice for CPAN which I love.
-
-=head2 How does this thing work?
-
-Imagine you don't have CPAN or CPANPLUS. You search for a module on the CPAN
-search site, download a tarball, unpack it and then run C<perl Makefile.PL> (or
-C<perl Build.PL>). If the module has dependencies you probably have to resolve
-those dependencies by hand before doing so. Then you run the unit tests and
-C<make install> (or C<./Build install>).
-
-cpanminus automates that.
-
 =head2 Zero-conf? How does this module get/parse/update the CPAN index?
 
 It queries the CPAN Meta DB site running on Google AppEngine at
@@ -182,58 +118,6 @@ automatically sets up local::lib compatible installation path in a C<perl5>
 directory under your home directory. To avoid this, run the script as the root
 user, with C<--sudo> option or with C<--local-lib> option.
 
-This L<local::lib> automatic integration is still considered alpha and
-in the work -- more bootstrapping is under development. Stay tuned.
-
-=head2 Does this really work?
-
-I tested installing MojoMojo, Task::Kensho, KiokuDB, Catalyst, Jifty and Plack
-using cpanminus and the installations including dependencies were mostly
-successful. More than I<half of CPAN> behaves really nicely and appears to
-work.
-
-However, there might be some distributions that will miserably fail, because of
-nasty edge cases. Here are some examples:
-
-=over 4
-
-=item *
-
-Packages uploaded to PAUSE in 90s which don't live under the standard
-C<authors/id/A/AA> directory hierarchy.
-
-=item *
-
-Distributions with a C<Makefile.PL> or C<Build.PL> that asks you questions
-without using C<prompt> function. However cpanminus has a mechanism to kill
-those questions with a timeout, and you can always say C<--interactive> to make
-the configuration interactive.
-
-=item *
-
-Distributions that do not shipped with C<META.yml> file but do require
-some specific version of toolchain for configuration.
-
-=item *
-
-Distributions that have a C<META.yml> file that is encoded in YAML 1.1 format
-using L<YAML::XS>. This will be eventually solved once we move to C<META.json>.
-
-=back
-
-cpanminus intends to work for 99.9% of modules on CPAN for 99.9% of people. It
-may not be perfect, but it should just work in most cases.
-
-If this tool doesn't work for your very rare environment, then I'm sorry, but
-you should use CPAN or CPANPLUS, or build and install modules manually.
-
-=head2 That sounds fantastic. Should I switch to this from CPAN(PLUS)?
-
-If you have CPAN or CPANPLUS working then you may want to keep using
-CPAN or CPANPLUS in the longer term, but I hope this can be a
-quite handy alternative to them for people in other situations. And
-apparently, many people love (at least the idea of) this software :)
-
 =head1 COPYRIGHT
 
 Copyright 2010- Tatsuhiko Miyagawa